package Gameplay;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import ADTs.PointADT;
import Gameplay.Weapon.Weapon;
import Gameplay.Weapon.Weapon0;
import Project.Constants;
import Project.Main;
import Project.MyGraphics;
import Project.RMath;
import Project.SaveFile;
/**
 * This class is a data structure containing player's hp,
 * player's maxHP, player's current Weapon, player's 
 * all kinds of movement's details and player's paint.
 * 
 * @author	Brian Wetherbee
 * 			Ryan McNamara
 * 			Zeng Yang
 *
 */
public class Player extends OnScreenObject implements IsLiving{
	private /*@ spec_public @*/ double HP; //current player's hp.
	protected /*@ spec_public @*/ double maxHP; // max hp value of current player
	private Weapon currWeapon;// current weapon that the player is using.
	
	
	
	
	
	/*@ requires Main.playerInLevel == true;
	  @ requires HP <= 0;
	  @ ensures Main.splayerInLevel == false;
	  @*/
	
	//A constructor for initializing a new player's hp and location
	public Player(){
		this(new PointADT(Constants.width / 2, Constants.height / 2),300);
	}
	
	//@ requires location != null;
	//@ requires HP > 0;
	//@ ensures currLevel = (Level)Main.getCurrentUI();
	//@ ensures this.HP == HP;
	//@ ensures this.maxHP = maxHP;
	//@ ensures maxAcceraltion >= 0;
	//@ ensures maxSpeed >= 0;
	//@ ensures radius > 0;
	//@ ensures currWeapon != null;
	public Player(PointADT location,double HP){
		currLevel = (Level)Main.getCurrentUI();
		this.HP = HP;
		this.maxHP = HP;
		velocity = new PointADT(0,0);
		setAcceleration(new PointADT(0,0));
		maxAcceleration = .0015;
		this.location = location.copy();
		maxSpeed = .4;
		radius = 32;
		this.wallBouncing = .5;
		currWeapon = new Weapon0(SaveFile.getCurrentFile().getWeaponUpgradeStatus().get(0),true);
		try {
			File f = new File("Pictures/player.png");			
			setDrawImage(ImageIO.read(f));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		this.movementBounds = new Rectangle(0,0,Constants.width,Constants.height - currLevel.barHeight);
	}
	
	//@ requires HP <= 0;
	public void Die(){
		currLevel.removeFromState(this);
	}
	
	//To draw a circle representing the player.
	public void paint(Graphics g){
		
		/*
		 * g.setColor(Color.RED); g.drawOval(location.getX()-getRadius(),
		 * location.getY()-getRadius(), getRadius()*2,getRadius()*2);
		 * 
		 * super.paint(gg);
		 */

		
		double ydiff = Main.getMouseLocation().getY() - this.location.getY();
		double xdiff = Main.getMouseLocation().getX() - this.location.getX();
		
		
		drawRotate = RMath.getAngle(xdiff, -ydiff);
		drawRotate -= 1 / 2.0 * Math.PI;
		drawRotate = 2 * Math.PI - drawRotate;
		super.paint(g);
      
//		g.drawImage(drawImage, location.getX() - radius, location.getY() - radius, null);
	
	}
	
	//moves based on information about which keys are pressed down in level
	public boolean move(){

		getAcceleration().setX(0);
		getAcceleration().setY(0);
		
		//add maxAcceleration to y direction
		if (currLevel.isUpPressed()) {
			getAcceleration().yAdd(maxAcceleration);
		}
		//add maxAcceleration to -y direction
		if (currLevel.isDownPressed()) {
			getAcceleration().yAdd(-maxAcceleration);
		}
		//add maxAcceleration to -x direction
		if (currLevel.isLeftPressed()) {
			getAcceleration().xAdd(-maxAcceleration);
		}
		//add maxAcceleration to x direction
		if (currLevel.isRightPressed()) {
			getAcceleration().xAdd(maxAcceleration);
		}
		
		//To create a projectile if player presses mouse event.
		if(currLevel.isFirePressed()){
			PointADT dest = currLevel.getMouseLocation();
			PointADT toSub = this.location.copy();
			toSub.scale(-1);
			dest = PointADT.addPoints(toSub, dest);
			dest.setY(dest.getY()*-1);
			currWeapon.fire(dest, this.location.copy());
		}
		return super.move();
		
	}
	
	
	


	/*@ requires currWeapon != null;
	  @ requires direction != null;
	  @ requires Main.playerInLevel == true;
	  @*/
	public void UseWeapon(PointADT direction){
		currWeapon.fire(direction,this.location.copy());
	}
	
	//@ requires newPoint != null;
	//@ ensures location == newPoint;
	public void setPoint(PointADT newPoint){
		location = newPoint;
	}

	public double getHP() {
		return HP;
	}

	//@ requires toTake > 0;
	//@ ensures HP = (\old HP - toTake);
	public void damage(double toTake) {
		HP -= toTake;
		if(HP < 0){
			this.Die();
		}
	}
	public double getMaxHP() {
		return this.maxHP;
	}
	public Weapon getWeapon() {
		return this.currWeapon;
	}
}
